package com.cheeven.cwliu.citation.steps;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpUtil {

	HttpClient httpclient = new DefaultHttpClient(new PoolingClientConnectionManager());

	public String get(String urlString) {
		try {
			Logger.getLogger(HttpUtil.class.getName()).log(Level.INFO, urlString);

			HttpGet httpget = new HttpGet(urlString);
			HttpResponse response = httpclient.execute(httpget);

			String rc = readResponse(response);
			Logger.getLogger(HttpUtil.class.getName()).log(Level.INFO, "Completed");
			
			return rc;

		} catch (ClientProtocolException ex) {
			Logger.getLogger(HttpUtil.class.getName()).log(Level.SEVERE, null, ex);
		} catch (IOException ex) {
			Logger.getLogger(HttpUtil.class.getName()).log(Level.SEVERE, null, ex);
		}
		return null;
	}

	public String post(String urlString, String[][] params) {
		try {
			Logger.getLogger(HttpUtil.class.getName()).log(Level.INFO, urlString);

			HttpPost httppost = new HttpPost(urlString);
			List<NameValuePair> nvps = new ArrayList<NameValuePair>();
			for (String[] param : params) {
				nvps.add(new BasicNameValuePair(param[0], param[1]));
			}

			httppost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));
			HttpResponse response = httpclient.execute(httppost);

			String rc = readResponse(response);
			Logger.getLogger(HttpUtil.class.getName()).log(Level.INFO, "Completed");
			return rc;
		} catch (ClientProtocolException ex) {
			Logger.getLogger(HttpUtil.class.getName()).log(Level.SEVERE, null, ex);
		} catch (IOException ex) {
			Logger.getLogger(HttpUtil.class.getName()).log(Level.SEVERE, null, ex);
		}
		return null;
	}

	private String readResponse(HttpResponse response) {
		StatusLine statusLine = response.getStatusLine();
		Logger.getLogger(HttpUtil.class.getName()).log(Level.INFO, String.valueOf(statusLine));

		// dump headers
		StringBuilder sb = new StringBuilder("Headers:");
		for (Header header : response.getAllHeaders()) {
			sb.append("\n\t").append(header.getName()).append(": ").append(header.getValue());
		}
		Logger.getLogger(HttpUtil.class.getName()).log(Level.FINEST, sb.toString());

		String charset = "UTF-8";
		if (response.getHeaders("Content-Type") != null) {
			for (Header h : response.getHeaders("Content-Type")) {
				String v = h.getValue();
				if (v.contains("charset=")) {
					charset = v.substring(v.indexOf("charset=") + 8);
				}
			}
		}

		if (statusLine != null) {
			if (statusLine.getStatusCode() == HttpURLConnection.HTTP_MOVED_TEMP) {
				String urlString = response.getHeaders("Location")[0].getValue();
				try {
					HttpEntity entity = response.getEntity();
					EntityUtils.consume(entity);
				} catch (IOException ex) {
					Logger.getLogger(HttpUtil.class.getName()).log(Level.SEVERE, null, ex);
				}
				Logger.getLogger(HttpUtil.class.getName()).log(Level.INFO, "Moved - {0}", urlString);
				return get(urlString);

			} else if (statusLine.getStatusCode() == HttpURLConnection.HTTP_OK) {
				InputStream is = null;
				try {
					HttpEntity entity = response.getEntity();
					is = entity.getContent();
					ByteArrayOutputStream out = new ByteArrayOutputStream();
					byte[] buffer = new byte[1024];
					int c = is.read(buffer);
					while (c != -1) {
						out.write(buffer, 0, c);
						c = is.read(buffer);
					}
					is.close();
					String s = out.toString(charset);
					EntityUtils.consume(entity);
					//Logger.getLogger(HttpUtil.class.getName()).log(Level.INFO, s);
					return s;
				} catch (IOException ex) {
					Logger.getLogger(HttpUtil.class.getName()).log(Level.SEVERE, null, ex);
				} catch (IllegalStateException ex) {
					Logger.getLogger(HttpUtil.class.getName()).log(Level.SEVERE, null, ex);
				} finally {
					try {
						is.close();
					} catch (IOException ex) {
						Logger.getLogger(HttpUtil.class.getName()).log(Level.SEVERE, null, ex);
					}
				}
			}
		} else {
			Logger.getLogger(HttpUtil.class.getName()).log(Level.WARNING, String.valueOf(statusLine.toString()));
			return null;
		}
		return null;
	}
}
